<?php
/**
 * @package es2reveng
 * @name ES2 .DBA/.HBA bitmap container unpacker
 * @author marco 'harddisk' schuster
 * @license GPL v3
 */
require 'helpers.php';
$f = $argv[1];
echo "viewing file $f\n";
if (!is_file($f))
	die("file broken");

$unpack_dir = $f.".unpacked/";
$ret = @mkdir($unpack_dir);
if ($ret === false)
	echo "warning: mkdir returned error, maybe directory already exists\n";

$fp = fopen($f, "rb");

//check magic bytes
$offset = -1; //the ++ incrementor will read at byte 1 if this is omitted
$magic = getchar($fp, ++$offset);
$magic .= getchar($fp, ++$offset);
$magic .= getchar($fp, ++$offset);
$magic .= getchar($fp, ++$offset);
if ($magic != "\x01\x00\x28\x00")
	die("wrong magic code. this is not a valid DBA/HBA file!\n");

//check file size
$b1 = getchar($fp, ++$offset, false);
$b2 = getchar($fp, ++$offset, false);
$b3 = getchar($fp, ++$offset, false);
$b4 = getchar($fp, ++$offset, false);
$flen = le_to_int($b1, $b2, $b3, $b4);
echo "file is $flen bytes long\n";
if ($flen + 8 != filesize($f)) //+8 because of four magic bytes and four length bytes
	echo "warning: file size in header (".($flen + 4)." bytes) differs from actual file size (".filesize($f)." bytes).\nthis file may contain strange stuff.\n";

//get the number of textures in the file
$b1 = getchar($fp, ++$offset, false);
$b2 = getchar($fp, ++$offset, false);
$b3 = getchar($fp, ++$offset, false);
$b4 = getchar($fp, ++$offset, false);
$num_textures = le_to_int($b1, $b2, $b3, $b4);
echo "file contains $num_textures textures/images\n";

//now, load the individual textures
for ($i = 0; $i < $num_textures; $i++) {
	//check for the magic begin byte sequence
	$magic = getchar($fp, ++$offset);
	$magic .= getchar($fp, ++$offset);
	$magic .= getchar($fp, ++$offset);
	$magic .= getchar($fp, ++$offset);
	if ($magic != "\x0e\x00\x28\x00")
		echo "warning for image $i: magic byte sequence wrong ('".strtohex($magic)."')!\n";

	//get the texture data length
	$b1 = getchar($fp, ++$offset, false);
	$b2 = getchar($fp, ++$offset, false);
	$b3 = getchar($fp, ++$offset, false);
	$b4 = getchar($fp, ++$offset, false);
	$tex_len = le_to_int($b1, $b2, $b3, $b4);

	$sf = fopen($unpack_dir."tex_$i.dbm", "wb");
	fwrite($sf, $magic.chr($b1).chr($b2).chr($b3).chr($b4));
	for ($j = 0; $j < $tex_len; $j++)
		fwrite($sf, getchar($fp, ++$offset));
	fclose($sf);
	echo "wrote image $i to ${unpack_dir}tex_$i.dbm\n";
	//jump over the separator NUL byte at the end of each file
	if (getchar($fp, ++$offset, false) != 0)
		echo "warning at offset $offset: jumping over something which is NOT a termination null byte!\n";

}
if ($offset + 1 != filesize($f)) //take care: offset is null-based, file-size is not
	echo "arrived at structural end (offset is $offset, flen is ".filesize($f)."), but there are still some bytes left\n";
else
	echo "file parse OK\n";

?>